diff --unified --new-file ../qmail-1.01-unmodified/Makefile ./Makefile
--- ../qmail-1.01-unmodified/Makefile	Tue Apr 15 07:05:23 1997
+++ ./Makefile	Wed Sep 10 12:39:32 1997
@@ -1522,12 +1522,12 @@
 load qmail-smtpd.o ip.o ipme.o ipalloc.o control.o constmap.o \
 received.o date822fmt.o now.o qmail.o fd.a wait.a datetime.a open.a \
 getln.a sig.a case.a env.a stralloc.a alloc.a substdio.a error.a \
-str.a fs.a auto_qmail.o socket.lib
+str.a fs.a auto_qmail.o dns.o dns.lib socket.lib syslog.lib
 	./load qmail-smtpd ip.o ipme.o ipalloc.o control.o \
 	constmap.o received.o date822fmt.o now.o qmail.o fd.a \
 	wait.a datetime.a open.a getln.a sig.a case.a env.a \
 	stralloc.a alloc.a substdio.a error.a str.a fs.a \
-	auto_qmail.o  `cat socket.lib`
+	auto_qmail.o dns.o  `cat dns.lib` `cat socket.lib` `cat syslog.lib`
 
 qmail-smtpd.0: \
 qmail-smtpd.8
diff --unified --new-file ../qmail-1.01-unmodified/qmail-smtpd.c ./qmail-smtpd.c
--- ../qmail-1.01-unmodified/qmail-smtpd.c	Tue Apr 15 07:05:23 1997
+++ ./qmail-smtpd.c	Wed Sep 10 12:39:37 1997
@@ -1,8 +1,20 @@
+#define BADRCPT 1
+#define SYSLOGGING 1
+#define DENYSPAM 1
+#define MAILFROMCHECK 1
+#define MAILFROMDNS 1
+/*zzz Version 0.9r1.0*/
 #include "sig.h"
 #include "readwrite.h"
 #include "getln.h"
 #include "stralloc.h"
 #include "substdio.h"
+#ifdef SYSLOGGING
+#ifdef __amigaos__ /* Work around syslog.h bug.  */
+#include <machine/ansi.h>
+#endif
+#include <syslog.h>
+#endif
 #include "alloc.h"
 #include "auto_qmail.h"
 #include "control.h"
@@ -19,6 +31,9 @@
 #include "env.h"
 #include "now.h"
 #include "exit.h"
+#ifdef MAILFROMDNS
+#include "dns.h"
+#endif
 
 #define MAXHOPS 100
 int timeout = 1200;
@@ -26,8 +41,8 @@
 char ssoutbuf[512];
 substdio ssout = SUBSTDIO_FDBUF(write,1,ssoutbuf,sizeof(ssoutbuf));
 
-void die() { substdio_flush(&ssout); _exit(1); }
-void flush() { if (substdio_flush(&ssout) == -1) _exit(1); }
+void die() { substdio_flush(&ssout); closelog (); _exit(1); }
+void flush() { if (substdio_flush(&ssout) == -1) { closelog (); _exit(1); } }
 void out(s) char *s; { if (substdio_puts(&ssout,s) == -1) die(); }
 
 int timeoutread(fd,buf,n) int fd; char *buf; int n;
@@ -44,9 +59,6 @@
 substdio ssin = SUBSTDIO_FDBUF(timeoutread,0,ssinbuf,sizeof(ssinbuf));
 
 
-void outofmem() { out("421 out of memory (#4.3.0)\r\n"); die(); }
-void sigalrm() { out("451 timeout (#4.4.2)\r\n"); die(); }
-
 struct qmail qqt;
 stralloc greeting = {0};
 int liphostok = 0;
@@ -58,6 +70,11 @@
 stralloc bmf = {0};
 struct constmap mapbmf;
 int flagbarf; /* defined if seenmail */
+#ifdef BADRCPT
+int brtok = 0;
+stralloc brt = {0};
+struct constmap mapbadrcptto;
+#endif
 
 stralloc helohost = {0};
 stralloc mailfrom = {0};
@@ -71,6 +88,25 @@
 char *remoteinfo;
 char *local;
 char *relayclient;
+#ifdef DENYSPAM
+char *denymail;
+#endif
+
+void outofmem()
+{
+#ifdef SYSLOGGING
+  syslog (LOG_ERR, "Out of memory while connected to %s!\n", remoteip);
+#endif
+  out("421 out of memory (#4.3.0)\r\n"); die();
+}
+
+void sigalrm()
+{
+#ifdef SYSLOGGING
+  syslog (LOG_INFO, "Connection to %s timed out.\n", remoteip);
+#endif
+  out("451 timeout (#4.4.2)\r\n"); die();
+}
 
 void dohelo(arg) char *arg;
 {
@@ -90,6 +126,9 @@
  remoteinfo = env_get("TCPREMOTEINFO");
  relayclient = env_get("RELAYCLIENT");
  dohelo(remotehost);
+#ifdef DENYSPAM
+ denymail = env_get("DENYMAIL");
+#endif
 }
 
 void straynewline()
@@ -230,16 +269,89 @@
  return 1;
 }
 
+#ifdef SYSLOGGING
+
+static void log_deny(m,f,t) char *m,*f,*t;
+{
+  syslog (LOG_INFO, "%s check failed (%s) -> (%s) [%s] (HELO %s)",
+          m, f, t, remoteip, helohost.s);
+} 
+
+#ifdef BADRCPT
+static void log_brt(s,r) char *s,*r;
+{
+  log_deny("Bad RCPT TO:", s, r);
+} 
+#endif
+
+static void log_bmf(s,r) char *s,*r;
+{
+  log_deny("Bad MAIL FROM:", s, r);
+} 
+
+static void log_ngw (char *s, char *r)
+{
+  log_deny ("Relayclient", s, r);
+}
+
+static void log_helo()
+{
+  syslog (LOG_INFO, "Received: from %s (HELO %s)\n", remotehost, helohost.s);
+} 
+
+#else /* not SYSLOGGING */
+#define log_brt(s,r)
+#define log_bmf(s,r)
+#define log_deny(m,f,t)
+#define log_helo()
+#endif /* not SYSLOGGING */
+
+#ifdef MAILFROMDNS
+int badmxcheck(dom) char *dom;
+{
+  ipalloc checkip = {0};
+  int ret=0;
+  stralloc checkhost = {0};
+
+  if (!*dom) return (DNS_HARD);
+  if (!stralloc_copys(&checkhost,dom)) return (DNS_SOFT);
+  
+  switch (dns_mxip(&checkip,&checkhost,1))
+  {
+    case DNS_MEM:
+    case DNS_SOFT:
+         ret=DNS_SOFT;
+         break;
+         
+    case DNS_HARD: 
+         ret=DNS_HARD; 
+         break;
+    case 1:
+         if (checkip.len <= 0) ret=DNS_HARD; 
+         break;
+  }
+
+  return (ret);
+}
+#endif
+
 int addrallowed()
 {
  int j;
  if (!rhok) return 1;
  j = byte_rchr(addr.s,addr.len,'@');
+#ifdef BADRCPT
+ if (brtok)
+    if (constmap(&mapbadrcptto, addr.s, addr.len - 1) ||
+        constmap(&mapbadrcptto, addr.s + j, addr.len - j - 1))
+       {log_brt(mailfrom.s,addr.s); return 0;}
+#endif
  if (j >= addr.len) return 1; /* can be taken care of by envnoathost */
  if (constmap(&maprcpthosts,addr.s + j + 1,addr.len - j - 2)) return 1;
  for (;j < addr.len;++j)
    if (addr.s[j] == '.')
      if (constmap(&maprcpthosts,addr.s + j,addr.len - j - 1)) return 1;
+ log_ngw (mailfrom.s, addr.s);
  return 0;
 }
 
@@ -251,7 +363,15 @@
  if (constmap(&mapbmf,addr.s,addr.len - 1)) { flagbarf = 1; return; }
  j = byte_rchr(addr.s,addr.len,'@');
  if (j < addr.len)
-   if (constmap(&mapbmf,addr.s + j,addr.len - j - 1)) flagbarf = 1;
+#ifdef DENYSPAM 
+ {
+#endif
+   if (constmap(&mapbmf,addr.s + j,addr.len - j - 1)) { flagbarf = 1; return; }
+#ifdef DENYSPAM 
+   /* allow for bulkemailer@ checking */
+   if (constmap(&mapbmf,addr.s, j + 1)) { flagbarf = 1; return; }
+ }  
+#endif
 }
 
 void smtp_greet(code) char *code; {
@@ -260,7 +380,11 @@
 void smtp_quit() { smtp_greet("221 "); out("\r\n"); die(); }
 void smtp_help() { out("214-qmail home page: http://pobox.com/~djb/qmail.html\r\n214 send comments to qmail@pobox.com\r\n"); }
 void err_syntax() { out("555 syntax error (#5.5.4)\r\n"); }
-void err_bmf() { out("553 sorry, your envelope sender is in my badmailfrom list (#5.7.1)\r\n"); }
+/* zzz 
+ void err_bmf() { out("553 sorry, your envelope sender is in my badmailfrom list (#5.7.1)\r\n"); }
+*/
+void err_bmf() { out("553 syntax error, please forward to your postmaster (#5.7.1)\r\n"); }
+void err_dns() { out("451 DNS temporary failure (#4.3.0)\r\n"); }
 void err_nogateway() { out("553 sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1)\r\n"); }
 void err_unimpl() { out("502 unimplemented (#5.5.1)\r\n"); }
 void err_seenmail() { out("503 one MAIL per message (#5.5.1)\r\n"); }
@@ -277,10 +401,87 @@
  seenmail = 0;
  out("250 flushed\r\n"); }
 void smtp_mail(arg) char *arg; {
+int i,j; char *why;
  if (seenmail) { err_seenmail(); return; }
  if (!arg) { err_syntax(); return; }
  if (!addrparse(arg)) { err_syntax(); return; }
  bmfcheck();
+ if (flagbarf) { log_bmf(addr.s,""); err_bmf(); return; }
+#ifdef DENYSPAM
+/************
+   DENYMAIL is set for this session from this client, 
+             so heavy checking of mailfrom
+   SPAM     -> refuse all mail
+   NOBOUNCE -> refuse null mailfrom
+   DNSCHECK -> validate Mailfrom domain
+************/
+
+ if (denymail)
+ {
+    why = denymail;
+    
+    if (!str_diff("SPAM", denymail)) 
+       flagbarf=1;
+    else
+      if (!addr.s[0] || !str_diff("#@[]", addr.s)) /*mjr*/
+     /* if (!addr.s[0]) */
+      {  
+         if (!str_diff("NOBOUNCE", denymail)) 
+            flagbarf=1;
+      }
+#ifdef MAILFROMCHECK
+      else
+      {
+        /*why = "Invalid.Mailfrom";*/
+        why = "MAIL FROM: syntax";
+        if ((i=byte_chr(addr.s,addr.len,'@')) >= addr.len)
+           flagbarf=1;       /* no '@' in from */
+        else
+        {
+          /* money!@domain.TLD */
+          if (addr.s[i-1] == '!') 
+             flagbarf=1;
+             
+          /* check syntax, visual */
+          if ((j = byte_rchr(addr.s+i, addr.len-i, '.')) >= addr.len-i)
+             flagbarf=1;  /* curious no '.' in domain.TLD */
+         
+          j = addr.len-(i+1+j+1);
+          if (j < 2 || j > 3)
+             flagbarf=1;  /* root domain, not a country (2), nor TLD (3)*/
+
+#ifdef MAILFROMDNS
+         if (!flagbarf)
+          if (!str_diff("DNSCHECK", denymail)) 
+          {
+           /* check syntax, via DNS */
+             why = "MAIL FROM: DNS";
+             switch (badmxcheck(&addr.s[i+1]))
+             {
+               case 0: 		break; /*valid*/
+               case DNS_SOFT:	flagbarf=2; /*fail tmp*/
+                                why = "(temporary) MAIL FROM: DNS";
+                                break;
+               case DNS_HARD: 	flagbarf=1; 
+               			break;
+             }
+          }
+#endif
+        }
+      }
+#endif
+
+    if (flagbarf)    
+    {
+      log_deny(why, addr.s, ""); 
+      if (2==flagbarf)
+         err_dns(); 
+      else
+         err_bmf();
+      return;
+    }
+ }/* denymail */
+#endif   
  seenmail = 1; out("250 ok\r\n");
  if (!stralloc_copys(&rcptto,"")) outofmem();
  if (!stralloc_copys(&mailfrom,addr.s)) outofmem();
@@ -289,7 +490,6 @@
  if (!seenmail) { err_wantmail(); return; }
  if (!arg) { err_syntax(); return; }
  if (!addrparse(arg)) { err_syntax(); return; }
- if (flagbarf) { err_bmf(); return; }
  if (relayclient)
   {
    --addr.len;
@@ -301,7 +501,8 @@
  out("250 ok\r\n");
  if (!stralloc_cats(&rcptto,"T")) outofmem();
  if (!stralloc_cats(&rcptto,addr.s)) outofmem();
- if (!stralloc_0(&rcptto)) outofmem(); }
+ if (!stralloc_0(&rcptto)) outofmem(); 
+}
 
 char accept_buf[FMT_ULONG];
 void acceptmessage(qp) unsigned long qp;
@@ -326,7 +527,8 @@
  qp = qmail_qp(&qqt);
  out("354 go ahead\r\n");
 
- received(&qqt,"SMTP",local,remoteip,remotehost,remoteinfo,case_diffs(remotehost,helohost.s) ? helohost.s : 0);
+ received(&qqt,"SMTP",local,remoteip,remotehost,remoteinfo,(r=case_diffs(remotehost,helohost.s)) ? helohost.s : 0);
+ if (r) log_helo();
  blast(&ssin,&hops);
  hops = (hops >= MAXHOPS);
  if (hops) qmail_fail(&qqt);
@@ -416,6 +618,15 @@
      bmfok = 1;
      if (!constmap_init(&mapbmf,bmf.s,bmf.len,0)) die();
   }
+#ifdef BADRCPT
+ switch(control_readfile(&brt,"control/badrcptto",0))
+  {
+   case -1: die();
+   case 1:
+     brtok = 1;
+     if (!constmap_init(&mapbadrcptto,brt.s,brt.len,0)) die();
+  }
+#endif
 }
 
 void main()
@@ -426,7 +637,18 @@
  sig_alarmcatch(sigalrm);
  sig_pipeignore();
 
- if (chdir(auto_qmail) == -1) die();
+#ifdef SYSLOGGING
+  openlog ("qmail-smtpd", 0, LOG_MAIL);
+#endif
+
+ if (chdir(auto_qmail) == -1)
+ {
+#ifdef SYSLOGGING
+   syslog (LOG_ERR, "Unable to switch to home directory (%s): errno=%m",
+           auto_qmail);
+#endif
+   die();
+ }
  getcontrols();
  getenvs();
 
@@ -446,4 +668,7 @@
    cmd.s[cmd.len++] = 0;
    doit(cmd.s);
   }
+#ifdef SYSLOGGING
+  closelog ();
+#endif
 }
